import JSEncrypt from "jsencrypt"

//加密公钥
const pubKeyPublicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1On71XvGrgvh0bTWh7fltpwGjFFiLT/6nhxb4ay/CdbwemrWQHhmS66pZI5BGQQZ1SU0dnzyUvpF0xKbBDAQEwHSSr0lsKQyU27EzV2VEzkHyRhqx4G8GsMlY1ESukAse5Ci3BuQuKqLJEosQNMToKwmEYE8peCBHNEV5iwmFJQIDAQAB'

//解密私钥
const pubKeyPrivate = 'MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALU6fvVe8auC+HRtNaHt+W2nAaMUWItP/qeHFvhrL8J1vB6atZAeGZLrqlkjkEZBBnVJTR2fPJS+kXTEpsEMBATAdJKvSWwpDJTbsTNXZUTOQfJGGrHgbwawyVjURK6QCx7kKLcG5C4qoskSixA0xOgrCYRgTyl4IEc0RXmLCYUlAgMBAAECgYAJxFlLSA6mO6zAOZKGY5jpu/Juo44SFAGZbcJjKQOt60J0M8pNNhISxPitTSldX+vFLmoliottSMf2DxMdnFQrBiueiHh1bEjyM4Uw3ejiEF7aFAFrxPa4wValIAj5AbksIbdTZJnuxLkYtfBWIAlBywUQHCap3XStLc/CxC7ygQJBANub1RVzGjSFA91uK3jEYz1kINwKJU58TFXxDt7sQiY9yKcEWIftsniMQnmDq+rtNCx03H+HcoY00gYbo9nKnMkCQQDTQoK9kg0wqU6RS7NHKbnBgbxVOgYp+dnzrTO661Z5TMR9QP2q70fltCODyeyGMN25FSda7Pfg646DVP20mb99AkAtrfxkucx5oDFtnbztIeyCmJE9M98OtEwslDfDpuEbkz5pfz3rCEZXTNWG8RyRgUWY+bXj0QjBYbtOCfHLG5oBAkB2NoFyEofO8u5D31gyOeb3oOEBz7YjRuvurryDm6yHs60/aV6Ih9xzbJly5Uq0zCNFrdCX0IHkGetlEenlZSMBAkAlygt0TcYne8KK7Tb2Us8RYXBDF/i0G+85jNlwWgFrxx3Ki7OIMO90bh7cr3EmDitQRUs6iQju2SUi9SJxttpq'

JSEncrypt.prototype.getkeylength = function () {
    return ((this.key.n.bitLength() + 7) >> 3);
};

// 分段解密，支持中文
JSEncrypt.prototype.decryptUnicodeLong = function (string) {
    var k = this.getKey();
    //解密长度=key size.hex2b64结果是每字节每两字符，所以直接*2
    var maxLength = ((k.n.bitLength() + 7) >> 3) * 2;
    try {
        var hexString = b64tohex(string);
        var decryptedString = "";
        var rexStr = ".{1," + maxLength + "}";
        var rex = new RegExp(rexStr, 'g');
        var subStrArray = hexString.match(rex);
        if (subStrArray) {
            subStrArray.forEach(function (entry) {
                decryptedString += k.decrypt(entry);
            });
            return decryptedString;
        }
    } catch (ex) {
        return false;
    }
};

// 分段加密，支持中文
JSEncrypt.prototype.encryptUnicodeLong = function (string) {
    let k = this.getKey();
    //根据key所能编码的最大长度来定分段长度。key size - 11：11字节随机padding使每次加密结果都不同。
    let maxLength = ((k.n.bitLength() + 7) >> 3) - 11;
    try {
        let subStr = "", encryptedString = "";
        let subStart = 0, subEnd = 0;
        let bitLen = 0, tmpPoint = 0;
        let len = string.length
        // debugger
        for (let i = 0; i < len; i++) {
            //js 是使用 Unicode 编码的，每个字符所占用的字节数不同
            let charCode = string.charCodeAt(i);
            if (charCode <= 0x007f) {
                bitLen += 1;
            } else if (charCode <= 0x07ff) {
                bitLen += 2;
            } else if (charCode <= 0xffff) {
                bitLen += 3;
            } else {
                bitLen += 4;
            }
            //字节数到达上限，获取子字符串加密并追加到总字符串后。更新下一个字符串起始位置及字节计算。
            if (bitLen > maxLength) {
                subStr = string.substring(subStart, subEnd)
                encryptedString += k.encrypt(subStr);
                subStart = subEnd;
                bitLen = bitLen - tmpPoint;
            } else {
                subEnd = i;
                tmpPoint = bitLen;
            }
        }
        subStr = string.substring(subStart, len)
        encryptedString += k.encrypt(subStr);
        return hex2b64(encryptedString);
    } catch (ex) {
        console.log(ex)
        return false;
    }
};

const b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const b64pad = "=";

function hex2b64(h) {
    var i;
    var c;
    var ret = "";
    for (i = 0; i + 3 <= h.length; i += 3) {
        c = parseInt(h.substring(i, i + 3), 16);
        ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
    }
    if (i + 1 == h.length) {
        c = parseInt(h.substring(i, i + 1), 16);
        ret += b64map.charAt(c << 2);
    } else if (i + 2 == h.length) {
        c = parseInt(h.substring(i, i + 2), 16);
        ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
    }
    while ((ret.length & 3) > 0) {
        ret += b64pad;
    }
    return ret;
}

const RsaUtil = {
    /**
     * 解密
     * @param res
     * @returns {string | false}
     */
    decrypt(res) {

        let encryptStr = new JSEncrypt()
        encryptStr.setPrivateKey(pubKeyPrivate)
        return encryptStr.decryptUnicodeLong(res)
    },
    /**
     * 加密
     * @param res
     * @returns {string | false}
     */
    encryption(res) {
        // 对字符串进行编码
        let encode = encodeURI(res);
        let encryptStr = new JSEncrypt()
        encryptStr.setPublicKey(pubKeyPublicKey)
        return encryptStr.encryptUnicodeLong(encode)
    }
}


export default RsaUtil

